﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace B09_SocketServer
{
    public partial class Form1 : Form
    {
        Dictionary <string,Socket> dic_Clients = new Dictionary<string, Socket>();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Btn_startListen_Click(object sender, EventArgs e)
        {
            //socketWatch
            Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //监听任意IP
            IPAddress ip = IPAddress.Any;
            //获取端口号
            IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(tbx_port.Text));
            //绑定端口号
            socketWatch.Bind(port);
            ShowMsg("绑定端口"+ port.ToString() + "成功");
            //监听端口
            socketWatch.Listen(10);
            Thread thread = new Thread(Listen);
            thread.IsBackground = true;
            thread.Start(socketWatch);
            this.btn_startListen.Enabled = false;
        }

        void ShowMsg(string msg)
        {
            tbx_RecieveArea.AppendText(msg + "\r\n");
        }

        /// <summary>
        /// 线程函数的参数类型只能是object
        /// </summary>
        /// <param name="obj"></param>
        void Listen(object obj)
        {
            ShowMsg("监听线程启动");
            Socket socket = obj as Socket;
            while (true)
            {
                Socket client = socket.Accept();
                string ip = client.RemoteEndPoint.ToString().Split(':')[0];
                dic_Clients[ip] = client;
                cbx_Clients.Items.Add(ip);
                ShowMsg(client.RemoteEndPoint.ToString() + "连接成功");
                //客户端连接成功后，服务器接收客户端发送的消息
                //byte[] buffer = new byte[1024 * 1024 * 2];
                //int r = client.Receive(buffer);
                //string str = Encoding.Default.GetString(buffer);
                //ShowMsg(str);
                Thread thread = new Thread(RecieveMsg);
                thread.IsBackground = true;
                thread.Start(client);
            }
        }

        void RecieveMsg(object obj)
        {
            Socket client = obj as Socket;

            byte[] buffer = new byte[1024 * 1024 * 2];
            while (true)
            {
                try
                {
                    int r = client.Receive(buffer);
                    if (r == 0) break;
                    string str = Encoding.UTF8.GetString(buffer, 0, r);
                    ShowMsg(client.RemoteEndPoint + ": " + str);
                }
                catch(Exception io)
                {
                    ShowMsg(io.ToString());
                    break;
                }
            }
        }
        /// <summary>
        /// 服务器给客户端发消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_sendMsg_Click(object sender, EventArgs e)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(tbx_sendArea.Text);
            if (dic_Clients.Count <= 0)
                return;
            try
            {

                if (cbx_Clients.Text != "")
                {
                    Socket socket = dic_Clients[cbx_Clients.Text];
                    socket.Send(buffer);
                }
                else
                {
                    foreach(KeyValuePair<string,Socket> kv in dic_Clients)
                    {
                        kv.Value.Send(buffer);
                    }
                }
            }
            catch { }
        }
    }
}
